package listener

import (
	"context"
	"gitee.com/goddesszz/gocommon/myutil"
	"github.com/go-redis/redis/v8"
	"github.com/sirupsen/logrus"
	"monoblog/common"
	"monoblog/config"
	"monoblog/domain/dao"
	"monoblog/domain/model"
)

func RunListeners() {
	// 创建 Redis 上下文
	ctx := context.Background()

	// 创建通知监听器实例
	momentListener := &MomentListener{
		redisClient: config.GetRedisClient(), // 从配置中获取 Redis 客户端
	}

	// 在单独的 goroutine 中启动监听，避免阻塞主程序
	go momentListener.StartListening(ctx) // 开始监听 Redis 通知频道
	logrus.Infof("Listeners 启动完成 ...")
}

// MomentListener 定义通知监听器接口
type MomentListener struct {
	redisClient *redis.Client
}

// StartListening 开始监听 Redis 通知频道
func (s *MomentListener) StartListening(ctx context.Context) {
	// 订阅目标频道
	pubsub := s.redisClient.Subscribe(ctx, common.REDIS_KEY_MOMENT_CHANNEL)
	defer pubsub.Close()

	// 接收订阅确认
	_, err := pubsub.Receive(ctx)
	if err != nil {
		logrus.Fatalf("订阅 Redis 频道失败: %v", err)
	}
	logrus.Infof("已开始监听 Redis 频道: %s", common.REDIS_KEY_MOMENT_CHANNEL)

	// 循环接收消息
	for {
		select {
		case <-ctx.Done():
			logrus.Info("监听器已停止")
			return
		case msg := <-pubsub.Channel():
			// 处理接收到的消息
			s.handleMoment(msg.Payload)
		}
	}
}

// 处理通知消息
// 具体的通知处理逻辑（如推送、存储等）
func (s *MomentListener) handleMoment(payload string) {
	logrus.Debugf("收到新动态moment: payload = %s", payload)

	// 反序列化 JSON 消息
	moment, err := myutil.JsonParse[model.Moment](payload)
	if err != nil {
		logrus.Errorf("解析JSON moment消息失败: %v, payload: %s", err, payload)
		return
	}

	momentRepository := dao.NewMomentRepository()

	//持久化
	exists, _ := momentRepository.ExistsByTopicTargetIdReceiver(moment.Topic, moment.TargetId, moment.Receiver)
	if !exists {
		err = momentRepository.Add(&moment)
		if err != nil {
			logrus.Errorf("新增moment失败: %v", err.Error())
		}
	} else {
		logrus.Infof("moment已存在, 无需新增: topic = %s, targetId = %s, receiver = %s", moment.Topic, moment.TargetId, moment.Receiver)
	}
}
